<?php
    class WZ_Utils
    {
        static $_instance;
		
		// singleton
		public function &getInstance() 
		{
            if (!self::$_instance instanceof self) {
				self::$_instance = new self();
			}
            return self::$_instance;
		}
        
        public static function vdump($dump, $exit = true)
        {
            var_dump($dump);
            if (true === $exit) {
                exit;
            }
        }
        
        public static function sl($str)
        {
            return stripslashes($str);
        }
        
        public static function verify($what, $comparison)
        {
            if (is_array($what) || is_object($what) || is_bool($what)) {
                return ($comparison === $what);
            } else {
                return ($comparison == $what);
            }
        }
        
        public static function r($a, $b, $str)
        {
            return str_replace($a, $a, $str);
        }
        
        public static function getUri()
        {
            $uri = $_SERVER['REQUEST_URI'];
            $uri = substr($uri, 1, strlen($uri));
            if (false === $uri) {
                return 'home';
            }
            return $uri;
        }
        
        public static function getvar($key)
        {
            return \WZ_Registry::get($key);
        }
        
        public static function setvar($key, $value)
        {
            \WZ_Registry::set($key, $value);
        }
        
        public static function get($key)
        {
            return \WZ_Registry::get($key);
        }
        
        public static function set($key, $value)
        {
            \WZ_Registry::set($key, $value);
        }
        
        public static function cut($a, $b, $str)
        {
            list($dummy, $seg) = explode($a, $str, 2);
            list($seg, $dummy) = explode($b, $seg, 2);
            return $seg;
        }
        
        public static function captcha($string, $size = 25, $ttf = 'webz0ne', $color = '80,80,80', $background = '226,226,226')
        {
            $hash = sha1($string . $size . $ttf . $color . $background);
            $string = '  ' . $string . '  ';
            $img = DIR_FILES . $hash . '.jpg';
            $return = \WZ_Url::getHome(false) . 'files/' . $hash . '.jpg';
            if (file_exists($img)) {
                return $return;
            } else {
                $angle = 0;
                $Leading = 0;
                $W = 0;
                $H = 0;
                $X = 0;
                $Y = 0;
                $_bx = imageTTFBbox($size, 0, DIR_FONTS . $ttf . '.ttf', $string);
                $str = explode("\n", $string);
                $nL  = count($str);
                $W   = ($W == 0) ? abs($_bx[2] - $_bx[0]) : $W;
                $H = ($H == 0) ? abs($_bx[5] - $_bx[3]) + ($nL > 1 ? ($nL * $Leading) : 0) : $H;
                // $H *= 1.4;
                // $W *= 1.06;
                $im = imagecreate($W, $H) or die("GD absente");
                $c = explode(",", $color);
                $b = explode(",", $background);
                $ct = imagecolorallocate($im, $c[0], $c[1], $c[2]);
                $bgc = imagecolorallocate($im, $b[0], $b[1], $b[2]);
                imagefilledrectangle($im, 0, 0, $W - 1, $H - 1, $bgc);
                imagettftext($im, $size, $angle, $X, $size, $ct, DIR_FONTS . $ttf . '.ttf', $string);
                imagejpeg($im, $img);
                imagedestroy($im);
                return $return;
            }
        }
        
        public static function makeCaptchaWord($stype = 'alphanum', $ct = 8)
		{
			$i = 1;
			$randStr = "";
			$randNum = "";
			$useList = "";
			$alpha = "A,B,C,D,E,F,G,H,,J,K,,M,N,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,,j,k,,m,n,,p,q,r,s,t,u,v,w,x,y,z";
			$secure = "!,@,$,%,&,*,-,_,=,+,?,~";
			if($stype == "alpha") {
				$randNum = 52;
				$useList = $alpha;
			} else if($stype == "alphanum") {
				$randNum = 62;
				$useList = $alpha . ",2,3,4,5,6,7,8,9";
			} else if($stype == "secure") {
				$randNum = 73;
				$useList = $alpha . ",2,3,4,5,6,7,8,9," . $secure;
			} else {
				$randNum = 10;
				$useList = "2,3,4,5,6,7,8,9";
			}

			$arr = array();
			$arr = explode(",", $useList);
			$randNum = count($arr);
			while(strlen($randStr) < $ct) {
				$randStr .= $arr[rand(0, $randNum - 1)];
			}
            return $randStr;
		}
        
        public static function aff_fo($str, $reverse = false)
        {
            if (false === $reverse) {
                if (!self::is_utf8($str)) {
                    $str = utf8_encode($str);
                }
            } else {
                if (self::is_utf8($str)) {
                    $str = utf8_decode($str);
                }
            }
            return self::sl($str);
        }
        
        public static function is_utf8($string) 
        {
            return !strlen(
                preg_replace(
                      ',[\x09\x0A\x0D\x20-\x7E]'            
                    . '|[\xC2-\xDF][\x80-\xBF]'             
                    . '|\xE0[\xA0-\xBF][\x80-\xBF]'         
                    . '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'  
                    . '|\xED[\x80-\x9F][\x80-\xBF]'         
                    . '|\xF0[\x90-\xBF][\x80-\xBF]{2}'      
                    . '|[\xF1-\xF3][\x80-\xBF]{3}'          
                    . '|\xF4[\x80-\x8F][\x80-\xBF]{2}'      
                    . ',sS',
                    '', 
                    $string
                )
            );
        }
        
        public static function curl($url, $config = array(), $method = 'GET')
        {
            if (!count($config)) {
                $config = array(
                    'curloptions' => array(
                        // CURLOPT_INFILE => $putFileHandle,
                        // CURLOPT_INFILESIZE => $putFileSize
                    )
                );
            }
            $adapter = new \Zend_Http_Client_Adapter_Curl();
            $client = new \Zend_Http_Client($url);
            $client->setAdapter($adapter);
            $adapter->setConfig($config);
            return $client->request($method);
        }
        
        public static function geturl($url, $proxy = null)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
            if (null !== $proxy) {
                curl_setopt($ch, CURLOPT_PROXY, $proxy);
            }
            $ip = rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array("REMOTE_ADDR: $ip", "HTTP_X_FORWARDED_FOR: $ip"));
            curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/" . rand(3, 5) . "." . rand(0, 3) . " (Windows NT " . rand(3, 5) . "." . rand(0, 2) . "; rv:2.0.1) Gecko/20100101 Firefox/" . rand(3, 5) . ".0.1");
            $page = curl_exec($ch);
            curl_close($ch);
            return $page;
        }
        
        public static function addAsset($asset, $ext = null)
        {
            if(null === $ext) {
                $ext = end(explode('.', strtolower($asset)));
            }
            if ($ext == 'css') {
                return '<link href="' . $asset . '" rel="stylesheet" type="text/css" media="all" />';
            } else if ($ext == 'js') {
                return '<script type="text/javascript" src="' . $asset . '"></script>';
            } else {
                return $asset;
            }
        }
        
        public static function isEmail($email)
        {
            return \Zend_Validate::is($email, 'EmailAddress');
        }
        
        public static function now()
        {
            return new \DateTime('now');
        }
        
        public static function infosIp($ipAddress = null)
        {
            if (null === $ipAddress) {
                $ipAddress = $_SERVER['REMOTE_ADDR'];
            }
            $query = sprintf("select * from pidgets.geoip where ip='%s'", $ipAddress);
            $queryUrl = "http://query.yahooapis.com/v1/public/yql?q=" . urlencode($query)."&format=json&env=".urlencode("store://datatables.org/alltableswithkeys");
            $json = file_get_contents($queryUrl);
            $data = json_decode($json, 1);
            if (isset($data['query']['results']['Result'])) {
                $ip = new \WZ_StoreObject;
                $ip->storename = 'WZIP';
                foreach ($data['query']['results']['Result'] as $key => $value) {
                    if ($key == 'ip') {
                        $key = 'value';
                    }
                    $setter = 'set' . ucfirst(strtolower($key));
                    $ip->$setter($value);
                }
                return $ip;
            }
            return null;
        }
        
        public static function geoIp($ipAddress = null)
        {
            if (null === $ipAddress) {
                $ipAddress = $_SERVER['REMOTE_ADDR'];
            }
            $infosIp = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip=' . $ipAddress));
            $ip = new \WZ_StoreObject;
            $ip->storename = 'WZIP';
            foreach ($infosIp as $key => $value) {
                $key = str_replace('geoplugin_', '', $key);
                $key = str_replace('request', 'iprequest', $key);
                $setter = 'set' . ucfirst(strtolower($key));
                $ip->$setter($value);
            }
            return $ip;
        }
        
        public static function geoIpNearby($coords = array())
        {
            if (count($coords)) {
                extract($coords);
                $host = "http://www.geoplugin.net/extras/nearby.gp?lat=" . $latitude . "&long=" . $longitude . "&radius={$radius}";
                if (is_numeric($limit)) {
                    $host .= "&limit={$limit}";
                }
            } else {
                $host = 'http://www.geoplugin.net/extras/nearby.gp?limit=20';
            }
            $infosNearby = unserialize(file_get_contents($host));
            $nearby = new \WZ_StoreObject;
            $nearby->storename = 'WZNearby';
            $i = 0;
            foreach ($infosNearby as $places) {
                $i++;
                $setterNearby = 'setPlace' . ucfirst(strtolower($i));
                $place = new \WZ_StoreObject;
                $place->storename = 'WZNearbyPlace';
                foreach ($places as $key => $value) {
                    $key = str_replace('geoplugin_', '', $key);
                    $key = str_replace('request', 'iprequest', $key);
                    $setter = 'set' . ucfirst(strtolower($key));
                    $place->$setter($value);
                }
                $nearby->$setterNearby($place);
            }
            return $nearby;
        }
        
        public static function arrayToObject($array = array()) 
		{
			if (is_array($array)) {
				$data = new stdClass;
				if (!count($array)) {
					return $data;
                }
				foreach ($array as $aKey => $aVal) {
					$data->{$aKey} = $aVal;
				}
                return $data;
			}
			return null;
		}
        
        public static function objectToArray($theseObjs)
		{
			if(is_object($theseObjs)) {
				$objects = array();
				foreach($theseObjs as $thisObj) {
                    $thisObject = array();
					foreach($thisObj as $key => $value) {
						$thisObject[$key] = $value;
					}
                    $objects[] = $thisObject;
				}
				return $objects;
			}
            return null;
		}
        
        public static function urlSite()
        {
            $urlsite = "http://" . $_SERVER["SERVER_NAME"] . dirname($_SERVER["SCRIPT_NAME"]) . "/";
	
            if (strstr($urlsite, '//')) {
                $urlsite = static::r('//', '/', $urlsite);
                $urlsite = static::r(':/', '://', $urlsite);
            }
            
            if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
                $urlsiteWin = '';
                $tab = explode('\\', $urlsite);
                foreach ($tab as $c => $v) {
                    $urlsiteWin .= $v;
                }
                $urlsiteWin = static::r('//', '/', $urlsiteWin);
                $urlsiteWin = static::r('http:/', 'http://', $urlsiteWin);
                $urlsite = $urlsiteWin;
            }
            
            static::set('urlsite', $urlsite);
        }
        
        public static function getMethods($obj, $needle = null)
        {
            if (version_compare(PHP_VERSION, '5.2.6') === -1) {
                $class        = new \ReflectionObject($obj);
                $classMethods = $class->getMethods();
                $methodNames  = array();

                foreach ($classMethods as $method) {
                    $methodNames[] = $method->getName();
                }
            } else {
                $methodNames = get_class_methods($obj);
            }
            
            if (null !== $needle) {
                $needleMethods = array();
                foreach ($methodNames as $method) {
                    if (5 < strlen($method) && $needle === substr($method, 0, strlen($needle))) {
                        $needleMethods[] = $method;
                    }
                }
                return $needleMethods;
            }
            
            return $methodNames;
        }
        
        public static function str_replace_first($search, $replace, $subject) 
        {
            return implode($replace, explode($search, $subject, 2));
        }
        
        public static function uuid() 
        {
            $node = self::env('SERVER_ADDR');

            if (strpos($node, ':') !== false) {
                if (substr_count($node, '::')) {
                    $node = str_replace(
                        '::', str_repeat(':0000', 8 - substr_count($node, ':')) . ':', $node
                    );
                }
                $node = explode(':', $node) ;
                $ipv6 = '' ;

                foreach ($node as $id) {
                    $ipv6 .= str_pad(base_convert($id, 16, 2), 16, 0, STR_PAD_LEFT);
                }
                $node =  base_convert($ipv6, 2, 10);

                if (strlen($node) < 38) {
                    $node = null;
                } else {
                    $node = crc32($node);
                }
            } elseif (empty($node)) {
                $host = self::env('HOSTNAME');

                if (empty($host)) {
                    $host = self::env('HOST');
                }

                if (!empty($host)) {
                    $ip = gethostbyname($host);

                    if ($ip === $host) {
                        $node = crc32($host);
                    } else {
                        $node = ip2long($ip);
                    }
                }
            } elseif ($node !== '127.0.0.1') {
                $node = ip2long($node);
            } else {
                $node = null;
            }

            if (empty($node)) {
                $node = crc32(sha1('DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi' . date('dmY')));
            }

            if (function_exists('zend_thread_id')) {
                $pid = zend_thread_id();
            } else {
                $pid = getmypid();
            }

            if (!$pid || $pid > 65535) {
                $pid = mt_rand(0, 0xfff) | 0x4000;
            }

            list($timeMid, $timeLow) = explode(' ', microtime());
            $uuid = sprintf(
                "%08x-%04x-%04x-%02x%02x-%04x%08x", (int)$timeLow, (int)substr($timeMid, 2) & 0xffff,
                mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3f) | 0x80, mt_rand(0, 0xff), $pid, $node
            );

            return $uuid;
        }
        
        public static function generateAuthKey() 
        {
            return sha1(self::uuid());
        }
        
        public static function cipher($text, $key) 
        {
            if (empty($key)) {
                trigger_error('You cannot use an empty key for cipher()', E_USER_WARNING);
                return null;
            }

            srand(\WZ_Config::read('Security.cipherSeed'));
            $out = '';
            $keyLength = strlen($key);
            for ($i = 0, $textLength = strlen($text); $i < $textLength; $i++) {
                $j = ord(substr($key, $i % $keyLength, 1));
                while ($j--) {
                    rand(0, 255);
                }
                $mask = rand(0, 255);
                $out .= chr(ord(substr($text, $i, 1)) ^ $mask);
            }
            srand();
            return $out;
        }
        
        public static function env($key) 
        {
            if ($key === 'HTTPS') {
                if (isset($_SERVER['HTTPS'])) {
                    return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
                }
                return (strpos(self::env('SCRIPT_URI'), 'https://') === 0);
            }

            if ($key === 'SCRIPT_NAME') {
                if (self::env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
                    $key = 'SCRIPT_URL';
                }
            }

            $val = null;
            if (isset($_SERVER[$key])) {
                $val = $_SERVER[$key];
            } elseif (isset($_ENV[$key])) {
                $val = $_ENV[$key];
            } elseif (getenv($key) !== false) {
                $val = getenv($key);
            }

            if ($key === 'REMOTE_ADDR' && $val === self::env('SERVER_ADDR')) {
                $addr = self::env('HTTP_PC_REMOTE_ADDR');
                if ($addr !== null) {
                    $val = $addr;
                }
            }

            if ($val !== null) {
                return $val;
            }

            switch ($key) {
                case 'SCRIPT_FILENAME':
                    if (defined('SERVER_IIS') && SERVER_IIS === true) {
                        return str_replace('\\\\', '\\', self::env('PATH_TRANSLATED'));
                    }
                    break;
                case 'DOCUMENT_ROOT':
                    $name = self::env('SCRIPT_NAME');
                    $filename = self::env('SCRIPT_FILENAME');
                    $offset = 0;
                    if (!strpos($name, '.php')) {
                        $offset = 4;
                    }
                    return substr($filename, 0, strlen($filename) - (strlen($name) + $offset));
                    break;
                case 'PHP_SELF':
                    return str_replace(env('DOCUMENT_ROOT'), '', self::env('SCRIPT_FILENAME'));
                    break;
                case 'CGI_MODE':
                    return (PHP_SAPI === 'cgi');
                    break;
                case 'HTTP_BASE':
                    $host = self::env('HTTP_HOST');
                    $parts = explode('.', $host);
                    $count = count($parts);

                    if ($count === 1) {
                        return '.' . $host;
                    } elseif ($count === 2) {
                        return '.' . $host;
                    } elseif ($count === 3) {
                        $gTLD = array(
                            'aero',
                            'asia',
                            'biz',
                            'cat',
                            'com',
                            'coop',
                            'edu',
                            'gov',
                            'info',
                            'int',
                            'jobs',
                            'mil',
                            'mobi',
                            'museum',
                            'name',
                            'net',
                            'org',
                            'pro',
                            'tel',
                            'travel',
                            'xxx'
                        );
                        if (in_array($parts[1], $gTLD)) {
                            return '.' . $host;
                        }
                    }
                    array_shift($parts);
                    return '.' . implode('.', $parts);
                    break;
            }
            return null;
        }
        
        public static function getFilesFromDir($dir, $ext = array('php', 'cgi'))
        {
           $return = array();
           if (is_dir($dir)) {
                $objects = scandir($dir);
                foreach ($objects as $object) {
                    if ($object <> "." && $object <> "..") {
                        if (filetype($dir . DIRECTORY_SEPARATOR . $object) == "dir") {
                            $return = array_merge($return, self::getFilesFromDir($dir . DIRECTORY_SEPARATOR . $object, $ext)); 
                        } else {
                            $file = $dir . DIRECTORY_SEPARATOR . $object;
                            $extFile = end(explode('.', $file));
                            if (in_array($extFile, $ext)) {
                                $return[] = $file;
                            }
                        }
                    }
                }
                reset($objects);
            }
            return $return;
        }
        
        public static function pagination($collection, $currentPageNumber = 1, $itemCountPerPage = 20, $pageRange = 5)
        {
            $paginator = \Zend_Paginator::factory($collection);
            $paginator->setCurrentPageNumber($currentPageNumber);
            $paginator->setItemCountPerPage($itemCountPerPage);
            $paginator->setPageRange($pageRange);
            // $paginator->getPages();
            return $paginator;
        }
        
        public static function logMessage($what, $message)
        {
            $log = \WZ_Store::getInstance('logs')->getStore();
            $collection = $log->getCollection();
            $newRow = array(
                'what' => $what,
                'message' => $message
            );
            $collection[] = $newRow;
            $log->setCollection($collection);
            $log->save();
        }
        
        public static function getLogMessage($display = false)
        {
            $log = \WZ_Store::getInstance('logs')->getStore();
            if (false === $display) {
                return $log->getCollection();
            } else {
                $html = '';
                foreach ($log->getCollection() as $tmpLog) {
                    extract($tmpLog);
                    $html .= '<h1>' . \WZ_Inflector::clean($what) . '</h1>';
                    $html .= '<i>' . \WZ_Inflector::clean($message) . '</i>';
                    $html .= '<hr />';
                }
                echo $html;
            }
        }
        
        public static function emptyDir($dir)
        {
            $sepdn = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? '\\' : '/';
            if (is_dir($dir))  {
                $objects = scandir($dir);
                foreach ($objects as $object) {
                    if ($object <> "." && $object <> "..") {
                        if (filetype($dir . $sepdn . $object) == "dir") {
                            self::emptyDir($dir . $sepdn . $object); 
                        } else {
                            @unlink($dir . $sepdn . $object);
                        }
                    }
                }
                reset($objects);
            }
        }
        
        public static function getBrowserLanguages() 
        {
			static $languages;
			if(is_array($languages)) {
                return $languages;
            }

			$languages = array();

			if(strlen(trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])) < 1) {
                return $languages;
            }
			if(!preg_match_all('/(\w+(?:-\w+)?,?)+(?:;q=(?:\d+\.\d+))?/', preg_replace('/\s+/', '', $_SERVER['HTTP_ACCEPT_LANGUAGE']), $matches)) {
                return $languages;
            }

			$priority=1.0;
			$languages = array();
			foreach($matches[0] as $def) {
				list($list, $q) = explode(';q=', $def);
				if(!empty($q)) {
                    $priority = floatval($q);
                }
				$list = explode(',', $list);
				foreach($list as $lang) {
					$languages[$lang] = $priority;
				}
			}
			arsort($languages);
			$languages = array_keys($languages);
			return $languages;
		}
        
		public static function getAvailableLanguages() 
        {
			$languages = array();
			$iterator = new \DirectoryIterator(DIR_TRAD);
			foreach($iterator as $file){
				if(!$file->isDot() && preg_match('/(\w+(-\w+)?)\.php$/', $file->getFilename(), $matches)){
					$languages[$matches[1]] = $file;
				}
			}
			return array_keys($languages);
		}
    }
    